﻿using GalaSoft.MvvmLight;
using JiveMessenger.Models;
using JiveMessenger.User;
using System.Linq;
using System;
using System.Collections.ObjectModel;
using JmShared;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System.Windows;
using System.Threading;
using System.ComponentModel;
using JiveMessenger.Utilities;
using System.Threading.Tasks;
using JiveMessenger.Log;
using System.Collections.Generic;
using Windows.UI.Xaml;
using GalaSoft.MvvmLight.Views;
namespace JiveMessenger.ViewModels
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class ViewModelManageGroup : ViewModelBaseEx, IViewModelManageGroup
    {
        private IClient _currentClient;
        private INavigationService _navigationService;
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public RelayCommand<IGroupMember> RemoveUserCommand { get; set; }
        public RelayCommand<IChatGroup> RenameGroupCommand { get; set; }
        public RelayCommand<IChatGroup> DeleteGroupCommand { get; set; }
        public RelayCommand RefreshMembersCommand { get; set; }

        public string[] GroupPrivileges { get; set; }



        private IChatGroup _chatGroup;
        public IChatGroup ChatGroup
        {
            get { return _chatGroup; }
            set
            {
                if (_chatGroup != value)
                {
                    Set(() => ChatGroup, ref _chatGroup, value);
                }
            }
        }

        private ObservableCollection<IGroupMember> _groupMembers;
        public ObservableCollection<IGroupMember> GroupMembers
        {
            get { return _groupMembers; }
            set
            {
                if (_groupMembers != value)
                {
                    Set(() => GroupMembers, ref _groupMembers, value);
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of the ViewModelManageGroupWindow class.
        /// </summary>
        public ViewModelManageGroup(IClient client,INavigationService navService, IChatGroup group)
        {
            this._currentClient = client;
            this._navigationService = navService;
            this.ChatGroup = group;


            if (group is JiveChatGroupModel)
            {
                RefreshGroupMembers();
            }
            GroupPrivileges = Enum.GetNames(typeof(GroupPrivilege));
            this.RemoveUserCommand = new RelayCommand<IGroupMember>(RemoveUserCommandAction, CanExecuteAsGroupAdmin);
            this.RenameGroupCommand = new RelayCommand<IChatGroup>(RenameGroupCommandAction,CanExecuteAsGroupAdmin);
            this.DeleteGroupCommand = new RelayCommand<IChatGroup>(DeleteGroupCommandAction, CanExecuteAsGroupOwner);
            this.RefreshMembersCommand = new RelayCommand(RefreshGroupMembers);
        }
        public ViewModelManageGroup() { }

        //private void __deleteMemberWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        //{
        //    Tuple<DatabaseQueryResponse, IGroupMember> response = (Tuple<DatabaseQueryResponse, IGroupMember>)e.Result;
        //    if (response.Item1.Success == true)
        //    {
        //        this.GroupMembers.Remove(response.Item2);
        //        Logger.Info("Group member {0} successfully removed from group {1}", response.Item2.Username, this.ChatGroup.Name);
        //    }
        //    else
        //    {
        //        Messenger.Default.Send(string.Format("An error occured while removing the member {0} from group {1}: {2}", response.Item2.Username, this.ChatGroup.Name));
        //        Logger.Warn("Could not remove the member {0} from group {1}: {2}", response.Item2.Username, this.ChatGroup.Name, response.Item1.StatusText);
        //    }
        //}

        //private void __deleteMemberWorker_DoWork(object sender, DoWorkEventArgs e)
        //{
        //    Tuple<ChatMessage,IGroupMember> args = (Tuple<ChatMessage,IGroupMember>)e.Argument;
        //    var result= _currentClient.Connection.RemoveMemberFromGroup(args.Item1);
        //    e.Result = new Tuple<DatabaseQueryResponse, IGroupMember>(result, args.Item2);
        //}

        private void RefreshGroupMembers()
        {
            this.GroupMembers = new ObservableCollection<IGroupMember>(((JiveChatGroupModel)this.ChatGroup).GroupMembers.Select(x =>
            {
                string nickname = string.Empty;
                var user = VmHelper.Locator.ViewModelContactList.Contacts.FirstOrDefault(contact => contact.UserName == x.Key);
                if (user != null)
                    nickname = user.NickName;
                return new JiveGroupMember(x.Key, nickname, x.Value);
            }));
           // this.GroupMembers.Add(new JiveGroupMember("test","foo", GroupPrivilege.Member));
        }

        private void DeleteGroupCommandAction(IChatGroup group)
        {
            switch (group.Type)
            {
                case GroupType.JiveChatGroup:
                    Messenger.Default.Send(new NotificationMessageAction<bool>(this, new JiveDialogMessage("Delete group?",string.Format("Are you sure you want to delete {0}?", group.Name)), "QueryDialog", async result =>
                    {
                        if (result == true)
                        {
                           // Messenger.Default.Send(new NotificationMessage(this, "CloseWindow"));
                            
                            await _currentClient.Connection.SendMessage(new ChatMessage(_currentClient.CurrentUserInfo.ID, _currentClient.CurrentUserInfo.UserName, MessageType.DeleteGroup) { Message = group.ID });
                        }
                    }));
                    break;
                default:
                    throw new NotImplementedException();
            }
        }

        private void RenameGroupCommandAction(IChatGroup group)
        {
           // Messenger.Default.Send(new NotificationMessage<IChatGroup>(this, group, "OpenRenameGroup")); 

            _navigationService.NavigateTo("RenameGroupPage", group);
        }




        private void ChangePrivilegeCommandAction(IGroupMember member)
        {
            throw new NotImplementedException();
        }


        private void RemoveUserCommandAction(IGroupMember member)
        {
            Messenger.Default.Send(new NotificationMessageAction<bool>(this, new JiveDialogQuery("Remove group member?",string.Format("Are you sure you want to remove {0} from {1}?", member.Username, this.ChatGroup.Name)), "QueryDialog", async result =>
                            {
                                if (result == true)
                                {
                                    ChatMessage msg = new ChatMessage(_currentClient.CurrentUserInfo.ID, _currentClient.CurrentUserInfo.UserName, MessageType.RemoveMemberFromGroup, this.ChatGroup.ID, member.Username);

                                    DatabaseQueryResponse response = await _currentClient.Connection.SendQuery(msg);

                                    if (response.Success == true)
                                    {
                                        this.GroupMembers.Remove(member);
                                        Logger.Info("Group member {0} successfully removed from group {1}", member.Username, this.ChatGroup.Name);
                                    }
                                    else
                                    {
                                        string errorText = string.Format("An error occured while removing the member {0} from group {1}: {2}", member.Username, this.ChatGroup.Name);
                                        Messenger.Default.Send(new NotificationMessage<string>(this, "Error", errorText, "MessageDialog"));
                                        Logger.Warn(errorText, response.StatusText);
                                    }
                                }
                            }));
        }

        private bool CanExecuteAsGroupOwner(IChatGroup group)
        {
            if (group == null || _currentClient.CurrentUserInfo == null)
                return false;
            if (group is JiveChatGroupModel)
            {
                var privilege = ((JiveChatGroupModel)group).GroupMembers.FirstOrDefault(x => x.Key == _currentClient.CurrentUserInfo.UserName).Value;
                if (privilege == GroupPrivilege.Owner)
                    return true;
            }
            return false;
        }

        private bool CanExecuteAsGroupAdmin(IChatGroup group)
        {
            if (group == null || _currentClient.CurrentUserInfo == null)
                return false;
            if (group is JiveChatGroupModel)
            {
                var privilege = ((JiveChatGroupModel)group).GroupMembers.FirstOrDefault(x => x.Key == _currentClient.CurrentUserInfo.UserName).Value;
                if (privilege == GroupPrivilege.Owner || privilege == GroupPrivilege.Moderator)
                    return true;
            }
            return false;
        }

        private bool CanExecuteAsGroupAdmin(IGroupMember member)
        {
            if (member == null || this._currentClient.CurrentUserInfo == null)
                return false;
            GroupPrivilege currentUserPrivilege = this.GroupMembers.FirstOrDefault(x => x.Username == this._currentClient.CurrentUserInfo.UserName).Privilege;
            if (currentUserPrivilege == GroupPrivilege.Owner)
            {
                if (member.Privilege == GroupPrivilege.Member || member.Privilege == GroupPrivilege.Moderator)
                    return true;
            }
            else if (currentUserPrivilege == GroupPrivilege.Moderator)
            {
                if (member.Privilege == GroupPrivilege.Member)
                    return true;
            }

            return false;
        }
        public override void Cleanup()
        {
            base.Cleanup();
        }
    }
}